# -*- encoding:utf-8 -*-

import base64
import datetime
import hashlib
import hmac
import json
import logging
import os
import threading
import time
import tkinter
import wave
from socket import *
from tkinter import *
from urllib.parse import quote

import pyaudio
import websocket
from websocket import create_connection

# from threading import Thread
from util.readconfig import ReadConfig


# reload(sys)
# sys.setdefaultencoding("utf8")
### 实时转写类
class RtasrClient():
    def __init__(self):
        myreadconfig = ReadConfig()
        self._isOver = False
        self._revResult = ""
        self._alltext = []

        self._rsIndex = 0

        self._stimes = datetime.datetime.now()
        self._ctimes = datetime.datetime.now()
        self._timItval = []
        self._tt = []

        my_config = myreadconfig.my_config
        self._my_config = my_config
        ts = str(int(time.time()))
        tt = (my_config["runtime_write_config"]["app_id"] + ts).encode('utf-8')
        md5 = hashlib.md5()
        md5.update(tt)
        baseString = md5.hexdigest()
        baseString = bytes(baseString, encoding='utf-8')

        apiKey = my_config["runtime_write_config"]["api_key"].encode('utf-8')
        signa = hmac.new(apiKey, baseString, hashlib.sha1).digest()
        signa = base64.b64encode(signa)
        signa = str(signa, 'utf-8')

        self.ws = create_connection(my_config["runtime_write_config"]["base_url"] + "?appid="
                                    + my_config["runtime_write_config"]["app_id"] + "&ts=" + ts + "&signa=" + quote(
            signa))
        self.trecv = threading.Thread(target=self.recv)
        self.trecv.start()

        self._runthread = threading.Thread(target=self.record)
        self._runthread.start()

    def record(self):
        # file_object = open(file_path, 'rb')  录音————————————————————录音
        now = datetime.datetime.now()
        global StyleTime, localaudio
        StyleTime = now.strftime("./audio/%Y_%m_%d_%H_%M")

        localaudio = now.strftime("./local_audio/%Y_%m_%d_%H_%M")


        global wf
        wf = wave.open(StyleTime, 'wb')  # 文件名可作为参数传入
        wf.setnchannels(self._my_config["record_config"]["CHANNELS"])  # 声道设置
        wf.setframerate(self._my_config["record_config"]["RATE"])  # 采样频率设置
        wf.setsampwidth(2)  # 采样位数设置

        try:
            p = pyaudio.PyAudio()
            # 创建音频流
            stream = p.open(format=pyaudio.paInt16,  # 音频流wav格式
                            channels=self._my_config["record_config"]["CHANNELS"],  # 单声道
                            rate=self._my_config["record_config"]["RATE"],  # 采样率16000
                            input=True,
                            frames_per_buffer=self._my_config["record_config"]["CHUNK"])

            print("- - - - - - - Start Recording ...- - - - - - - ")

            self._stimes = datetime.datetime.now()  # 录音开始计时
            # index = 1  #如果要分段保存可能需要计数或者使用计时,但是感觉要新开一个线程
            while True:

                if self._isOver:
                    print("record is break by user!..")
                    break

                chunk = stream.read(self._my_config["record_config"]["CHUNK"])
                # data = copy.deepcopy(chunk)

                if not chunk:
                    break

                self.ws.send(chunk)
                wf.writeframes(chunk)  #音频缓存写入
                # index += 1
                time.sleep(0.04)
        except Exception as e:
            print('ERROR:', e)  # 出现服务中断 ，再次调用麦克风进行本地录音记录
            wf.close()
            p.terminate()
            time.sleep(1)

            global locawf
            locawf = wave.open(localaudio, 'wb')  # 文件名可作为参数传入
            locawf.setnchannels(self._my_config["record_config"]["CHANNELS"])  # 声道设置
            locawf.setframerate(self._my_config["record_config"]["RATE"])  # 采样频率设置
            locawf.setsampwidth(2)  # 采样位数设置

            localp = pyaudio.PyAudio()  # 创建音频流
            localstream = localp.open(format=pyaudio.paInt16,  # 音频流wav格式
                                      channels=self._my_config["record_config"]["CHANNELS"],  # 单声道
                                      rate=self._my_config["record_config"]["RATE"],  # 采样率16000
                                      input=True,
                                      frames_per_buffer=self._my_config["record_config"]["CHUNK"])
            print("- - - - - - -local Start Recording ...- - - - - - - ")

            while True:
                if self._isOver:
                    print("record is break by user!..")
                    break
                localchunk = localstream.read(self._my_config["record_config"]["CHUNK"])
                if not localchunk:
                    break
                locawf.writeframes(localchunk)  #音频缓存写入
                time.sleep(0.04)
        finally:
            print("send over... ")

        self.ws.send(bytes(self._my_config["record_config"]["end_tag.encode"]('utf-8')))
        print("send end tag success")

    def recv(self):
        try:
            while self.ws.connected:
                result = str(self.ws.recv())
                if len(result) == 0:
                    print("receive result end")
                    break
                result_dict = json.loads(result)
                # 解析结果
                if result_dict["action"] == "started":
                    print("handshake success, result: " + result)

                if result_dict["action"] == "result":
                    result_1 = result_dict
                    # result_2 = json.loads(result_1["cn"])
                    # result_3 = json.loads(result_2["st"])
                    # result_4 = json.loads(result_3["rt"])
                    # t.insert(END, result_1["data"])
                    print(type(result_1["data"]))  # str
                    # print("转写结果: : " + result_1["data"])
                    # ditret=eval(result_1["data"])  #dict
                    ditret = json.loads(result_1["data"])

                    rst = ""

                    for i in ditret["cn"]['st']['rt']:
                        for j in i['ws']:
                            for w in j['cw']:
                                rst += w['w']

                    print("转写结果: : " + rst)

                    if (ditret["cn"]['st']['type'] == "0"):
                        self._alltext.append(rst)

                        self._ctimes = datetime.datetime.now()  # 获取本次的转写时间
                        tim_intval = int((self._ctimes - self._stimes).total_seconds())  # 计算时间间隔
                        tim_item = '会议第' + str(tim_intval) + "秒的内容"
                        self._timItval.append(tim_item)
                        str_t = rst + "                :______________" + tim_item

                        self._tt.append(str_t)

                        # rst = "【最终识别】" + rst
                        self._rsIndex = self._rsIndex + 1
                        self._revResult = {
                            "type": 0,
                            "index": self._rsIndex,
                            "content": rst
                        }


                    else:

                        self._revResult = {
                            "type": 1,
                            "index": self._rsIndex,
                            "content": rst
                        }

                        # "识别结果追加：：："
                        print(str(self._alltext))

                if result_dict["action"] == "error":
                    print("rtasr error: " + result)
                    self.ws.close()
                    return
                if self._isOver:
                    print("ws is break by user!..")
                    self.ws.close()
                    return
        except websocket.WebSocketConnectionClosedException:
            print("receive result end")

    def readInfo(self):
        return self._revResult

    def allInfo(self):
        return self._alltext

    def Cal_interval(self):
        return self._tt

    def close(self):  # 关闭云端的服务链接
        global wf,localwf
        self._isOver = True
        self.ws.close()

        global StyleTime##### WAV  转 MP3  格式
        otherStyleTime = StyleTime + '.mp3'
        # os.system('ffmpeg -i %s  test1.mp3' % (wave_out_path)) #转换名也可使用传入的文件名参数
        os.system('ffmpeg -i %s  %s' % (StyleTime, otherStyleTime))  # 将录音转换为MP3格式
        wf.close()  # 关闭文件

        global localaudio
        localaudios = localaudio+'.mp3'
        os.system('ffmpeg -i %s   %s' %(localaudio,localaudios))
        localwf.close()


        time.sleep(1)
        print("connection closed")

def thread_it(func, *args):
    t = threading.Thread(target=func, args=args)
    t.setDaemon(True)
    t.start()

def run():
    # 开始录音，并向远方发送识别信息
    client = RtasrClient()
    client.send()

if __name__ == '__main__':
    logging.basicConfig()

    root = Tk()
    t = Text(root)
    t.pack()

    tkinter.Button(root, text='开始录音', command=lambda: thread_it(run, )).pack()
    root.mainloop()
